﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PGMHelper;

namespace WSAP
{
    /***
     * 矩形板测试
     * 使用AddShell增加壳单元
     * 使用FixLine PinLine实现线约束
    ****/

    /// <summary>
    /// 矩形板测试
    /// </summary>
    class WSAPRecSlab
    {
        /// <summary>
        /// 四边固接
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="thickness"></param>
        /// <param name="nodeLoad"></param>
        /// <param name="meshSize"></param>
        /// <returns></returns>
        public static bool FixExample(double width, double height, double thickness, double nodeLoad, double meshSize)
        {
            //获得模型
            var model = WSAPRecSlab.GetWModelNet(width, height, thickness, nodeLoad, meshSize);
            //增加线约束
            model.FixLine(0, 0, 0, width, 0, 0);
            model.FixLine(width, 0, 0, width, height, 0);
            model.FixLine(width, height, 0, 0, height, 0);
            model.FixLine(0, 0, 0, 0, height, 0);
            //创建有限元模型
            if (!model.CreateFEModel(false)) return model.ShowWarningError();
            //求解
            if (!model.DoLinearStaticAnalyze()) return model.ShowWarningError();
            //绘图
            model.ToGraphics(new StructrueChartParam
            {
                DOF = 3,
                isNodeMaxResponseShow = true,
                ChartType = StructureChartType.SlabOnly,
            });
            return true;
        }

        /// <summary>
        /// 四边铰接
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="thickness"></param>
        /// <param name="nodeLoad"></param>
        /// <param name="meshSize"></param>
        /// <returns></returns>
        public static bool PinExample(double width, double height, double thickness, double nodeLoad, double meshSize)
        {
            //获得模型
            var model = WSAPRecSlab.GetWModelNet(width, height, thickness, nodeLoad, meshSize);
            //增加线约束
            model.PinLine(0, 0, 0, width, 0, 0);
            model.PinLine(width, 0, 0, width, height, 0);
            model.PinLine(width, height, 0, 0, height, 0);
            model.PinLine(0, 0, 0, 0, height, 0);
            //创建有限元模型
            if (!model.CreateFEModel(false)) return model.ShowWarningError();
            //求解
            if (!model.DoLinearStaticAnalyze()) return model.ShowWarningError();
            //绘图
            model.ToGraphics(new StructrueChartParam
            {
                DOF = 3,
                isNodeMaxResponseShow = true,
                ChartType = StructureChartType.SlabOnly,
            });
            return true;
        }

        /// <summary>
        /// 建立算例有限元模型
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="meshSize"></param>
        /// <returns></returns>
        private static WModelNet GetWModelNet(double width, double height, double thickness, double nodeLoad, double meshSize)
        {
            //初始化模型参数
            var model = new WModelNet();
            //计算剖分数目
            int xMeshNumber = (int)(width / meshSize);
            int yMeshNumber = (int)(height / meshSize);
            //防止剖分数为零
            if (xMeshNumber == 0) xMeshNumber = 1;
            if (yMeshNumber == 0) yMeshNumber = 1;
            //节点编号倍数
            int nodeTagFactor = 1000;
            //长度增量
            var xDletaLength = width / xMeshNumber;
            var yDletaLength = height / yMeshNumber;
            var nodeTagList = new List<int>();
            //宽
            for(int x = 0; x <= xMeshNumber; x++)
            {
                //长
                for(int y = 0; y <= yMeshNumber; y++)
                {
                    //计算坐标
                    int nodeTag = y * nodeTagFactor + x;
                    nodeTagList.Add(nodeTag);
                    //添加节点
                    model.AddNode(nodeTag, xDletaLength * x, yDletaLength * y, 0);
                    //添加节点荷载
                    model.AddNodeLoad(nodeTag, 3, -nodeLoad);
                    //判断是否要添加单元
                    if (x == 0 || y == 0) continue;
                    //添加单元
                    model.AddShell((y - 1) * nodeTagFactor + x - 1,
                        (y - 1) * nodeTagFactor + x,
                        nodeTag, y * nodeTagFactor + x - 1, thickness);
                }
            }
            //返回模型
            return model;
        }
    }
}
